package com.hzy.wechat.aspectj;

import com.hzy.wechat.annotation.FeignCache;
import com.ruoyi.common.utils.redis.RedisUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * @author lianghaoteng
 */
@Aspect
@Component
public class FeignClientAspect implements InitializingBean {


    private static final String FEIGN_CLIENT_CACHE_PREFIX = "FEIGN-CLIENT-CACHE-";

    /**
     * 缓存rpc调用的环绕通知
     * @param joinPoint
     * @return 目标方法调用的结果
     * @throws Throwable
     */
    @Around("@annotation(com.hzy.wechat.annotation.FeignCache)")
    public Object cacheAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String key = FEIGN_CLIENT_CACHE_PREFIX + joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName() + "#" + SimpleKeyGenerator.generateKey(joinPoint.getArgs());
        Object cache =  RedisUtils.getCacheObject(key);
        if (cache != null) {
            return cache;
        }
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        FeignCache annotation = signature.getMethod().getAnnotation(FeignCache.class);
		// 这里可以对结果进行过滤，缓存正确的结果，视具体的业务逻辑来定
        cache = joinPoint.proceed(joinPoint.getArgs());
        if ( annotation.expiresIn() > 0) {
            RedisUtils.setCacheObject(key, cache, Duration.ofSeconds(annotation.expiresIn()));
        }
        return cache;
    }

	/**
	这个方法的作用是：启动项目之前先把feign的缓存都清除掉，视具体情况而定
	*/
    @Override
    public void afterPropertiesSet() {
//        Set<String> keys = redisTemplate.keys(FEIGN_CLIENT_CACHE_PREFIX + "*");
//        if (keys != null && keys.size() > 0) {
//            redisTemplate.unlink(keys);
//        }
    }
}
